home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
UTIL
/
MEMORY
/
OLD
/
MEM208SRC
/
!Memphis
/
c
/
sprstore
< prev
Wrap
Text File
|
1993-09-08
|
7KB
|
311 lines
/*
* sprstore.c
* Part of the !Memphis distribution
* (c) bdb/nas, 1991-3
*/
/* #define DEBUG */
/* includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"
#include "sprite.h"
#include "util.h"
#include "core.h"
#include "spr.h"
#include "Lfile.h"
#include "store.h"
/* debug support */
#ifdef DEBUG
#define DEBUGF printf
#else
#define DEBUGF 1?(void)0:(void)printf
#endif
/* vars */
#define ROOTFILETYPE 0x3F1 /* Acorn-allocated */
#define STOREHANDBUFSIZE 10
/* storeid will be NULL for sprite area, or else a ptr to this */
struct storeid
{ char basename[256];
LHANDLE storehandle[STOREHANDBUFSIZE]; /* OS file handle */
int storeinode[STOREHANDBUFSIZE]; /* inode number or -1 */
int nextone;
storeid next;
};
static storeid thestoreids;
static DEFERR( mb_Lostsprite, 0, "sprite lost" );
static DEFERR( mb_Lostfile, 0, "host file lost" );
/*
* store interface part defines
*/
typedef struct file_header
{ sprite_header h;
char data[4];
} file_header;
/*
* Root Lfile header
*/
typedef struct root_header
{
char id[4]; /* "MemF" */
char ctype; /* compression type, 1 = squash */
char res1; /* reserved, must be 0 */
char res2;
char res3;
} root_header;
#define FHSIZE ( sizeof( file_header )-4 )
#define ASERROR ==_kernel_ERROR?_kernel_last_oserror():NULL
static file_header *findstoresprite( int inode ) /* Find sprite for an inode*/
{ SPRITENAME sname;
sprintf( sname.name, "mfs%08x", inode );
return (file_header *)findsprite( sname );
}
static char *storename(storeid s,int inode ) /* Make host file name for an inode*/
{ static char buf[256],*b1;
strcpy(buf,s->basename);
b1 = strrchr(buf,';');
if (b1)
{ *b1 = ':';
if (b1>buf && b1[-1]==';')
b1[-1]=':';
}
b1=buf+strlen(buf);
while (inode>0)
{ char b[4];
sprintf(b,",.%c","0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[inode%36]);
strins(b1,b);
inode/=36;
}
return buf;
}
static int storefindh( storeid s,int inode ) /* Open host file for an inode*/
{ char *p;
int n;
for (n=0;n<STOREHANDBUFSIZE;n++)
if (s->storeinode[n]==inode)
return n;
n = s->nextone;
if (++s->nextone>=STOREHANDBUFSIZE)
s->nextone=0;
if (s->storeinode[n]!=-1 && s->storehandle[n])
Lclose(s->storehandle[n]);
p=storename(s,inode);
if (Lopen(p,&s->storehandle[n]))
s->storehandle[n]=NULL;
s->storeinode[n]=inode;
DEBUGF("storefindhand(%d),%s=%d\n",inode,p,n);
return n;
}
static LHANDLE storefindhand( storeid s,int inode ) /* Open host file for an inode*/
{
return s->storehandle[storefindh(s,inode)];
}
_kernel_oserror *Store_Init(void) /* Initialise store subsystem*/
{
DEBUGF("Store_Init\n");
thestoreids = NULL;
return Linit();
}
void Store_Flush(void)
{ storeid s,t;
for (s=thestoreids;s;s=t)
{ int i;
for (i=0;i<STOREHANDBUFSIZE;i++)
{ if (s->storeinode[i]!=-1 && s->storehandle[i])
Lclose(s->storehandle[i]);
s->storeinode[i]=-1;
}
t = s->next;
}
}
_kernel_oserror *Store_Finish(void) /* Terminate store subsystem*/
{ storeid s,t;
Store_Flush();
for (s=thestoreids;s;s=t)
{ t = s->next;
free(s);
}
thestoreids = NULL;
return Lfinish();
}
storeid Store_Find( char *special_field, char *volume ) /* Find a storeid*/
{ storeid s;
int i;
volume = volume;
DEBUGF("Store_Find %s %s\n",special_field?special_field:"NULL",volume?volume:"NULL");
if (!special_field)
return NULL;
for (s=thestoreids;s;s=s->next)
if (!strcmp(s->basename,special_field))
return s;
s = calloc(1,sizeof(struct storeid));
strcpy(s->basename,special_field);
for (i=0;i<STOREHANDBUFSIZE;i++)
s->storeinode[i]=-1;
s->next = thestoreids;
s->nextone = 0;
thestoreids = s;
return s;
}
_kernel_oserror *Store_Read(storeid s, int inode, int offset, int length, void *ptr)
{
DEBUGF("Store_Read(%s,%d,%d,%d,%p)\n",s?s->basename:"Mem",inode,offset,length,ptr);
if (s)
{ LHANDLE p=storefindhand(s,inode);
if (!p)
return ERR(mb_Lostfile);
return Lread(p,offset,length,ptr);
}
else
{ file_header *h=findstoresprite(inode);
if (!h)
return ERR(mb_Lostsprite);
memcpy( ptr, &h->data[offset], length );
return NULL;
}
}
_kernel_oserror *Store_Write(storeid s,int inode, int offset, int length, void *ptr )
{
DEBUGF("Store_Write(%s,%d,%d,%d,%p)\n",s?s->basename:"Mem",inode,offset,length,ptr);
if (s)
{ LHANDLE p=storefindhand(s,inode);
if (!p)
return ERR(mb_Lostfile);
return Lwrite(p,offset,length,ptr);
}
else
{ file_header *h=findstoresprite(inode);
if (!h)
return ERR(mb_Lostsprite);
memcpy( &h->data[offset], ptr, length );
return NULL;
}
}
_kernel_oserror *Store_SetLength( storeid s,int inode, int length )
{ DEBUGF("Store_SetLength(%s,%d,%d)\n",s?s->basename:"Mem",inode,length);
if (s)
{ int n=storefindh(s,inode);
_kernel_osfile_block b;
if (length==0)
{ if (s->storehandle[n])
{ Lclose(s->storehandle[n]);
s->storehandle[n]=0;
return _kernel_osfile(6,storename(s,inode),&b) ASERROR;
}
else
return NULL;
}
else
{ int h=storefindh(s,inode);
if (s->storehandle[h])
return Lsetlength(s->storehandle[h],length);
else
{ _kernel_oserror *err;
char *p,*n;
s->storeinode[h]=-1;
err = Lcreate(n=storename(s,inode),length);
if (err)
{ for (p=n;*p;p++)
if (*p=='.')
{ *p=0;
_kernel_osfile(8,n,&b);
*p='.';
}
err = Lcreate(n=storename(s,inode),length);
}
/* Create root inode */
if (!inode)
{ root_header root;
b.load=ROOTFILETYPE;
_kernel_osfile(18,n,&b);
strcpy(root.id, "MemF");
root.ctype = 1; root.res1 = 0; root.res2 = 0; root.res3 = 0;
}
DEBUGF("Create %s len %d %s\n",n,length,err?"ERR":"OK");
return err;
}
}
}
else
{
file_header *h=findstoresprite( inode );
if (length==0)
{ if (h)
deletesprite(&h->h);
return NULL;
}
else
{ length = ((length-1)|127)+1;
if (h)
return setspritesize( &h->h, length+FHSIZE-SHSIZE );
else
{ sprite_header *h;
SPRITENAME sname;
sprintf( sname.name, "mfs%08x", inode );
return createsprite( sname, length+FHSIZE-SHSIZE, &h );
}
}
}
}
_kernel_oserror *Store_FreeSpace( storeid s, struct freespace *b )
{ _kernel_swi_regs r;
_kernel_oserror *err=NULL;
if (!s)
spritefreespace(b);
else
{ r.r[0]=49;
r.r[1]=(int)storename(s,0);
err=_kernel_swi(OS_FSControl,&r,&r);
b->free=r.r[0];
b->biggest = r.r[1];
b->size = r.r[2];
}
return err;
}
char * Store_Name( storeid s )
{ char *p;
if (!s)
return "Sprites";
p=strrchr(s->basename,'.');
if (p)
return p+1;
else
return s->basename;
}
char * Store_SpecialField( storeid s )
{
if (!s)
return NULL;
return s->basename;
}